Skip to content

feat(account-keychain): implement TIP-1053 nonces#3838

Open
legion2002 wants to merge 15 commits intomainfrom
feat/tip-1053-key-authorization-nonce
Open

feat(account-keychain): implement TIP-1053 nonces#3838
legion2002 wants to merge 15 commits intomainfrom
feat/tip-1053-key-authorization-nonce

Conversation

@legion2002
Copy link
Copy Markdown
Contributor

@legion2002 legion2002 commented May 6, 2026

Implements TIP-1053 key authorization nonces behind T5 using the simplified nonce-presence semantics from the spec PR. Present nonce fields are included in the signed key authorization and consumed per account on successful authorization; absent nonce fields preserve legacy byte-equivalent encodings. Adds T5-gated AccountKeychain selectors to authorize with a nonce, burn a nonce, and query nonce consumption.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

⚠️ Changelog not found.

A changelog entry is required before merging. We've generated a suggested changelog based on your changes:

Preview
---
tempo-contracts: minor
tempo-precompiles: minor
tempo-node: patch
---

Added TIP-1053 key-authorization nonce support to the account keychain precompile, including new `authorizeKey(..., nonce)` and `burnKeyAuthorizationNonce` entrypoints, an `isKeyAuthorizationNonceUsed` view, replay-protection storage, and a T5 hardfork selector schedule. Extended integration and gas-estimation tests to cover nonce consumption, replay rejection, and pending-replay eviction.

Add changelog to commit this to your branch.

@legion2002 legion2002 force-pushed the feat/tip-1053-key-authorization-nonce branch from 45873c0 to a37532b Compare May 7, 2026 11:10
@legion2002 legion2002 force-pushed the feat/tip-1053-key-authorization-nonce branch from 1e29a90 to 34a663c Compare May 7, 2026 12:03
@legion2002 legion2002 changed the base branch from main to docs/tip-1053-nonce-presence May 7, 2026 12:03
@legion2002 legion2002 marked this pull request as ready for review May 7, 2026 12:20
@legion2002 legion2002 added the cyclops Trigger Cyclops PR audit label May 7, 2026
Base automatically changed from docs/tip-1053-nonce-presence to main May 7, 2026 12:40
Copy link
Copy Markdown

@tempoxyz-cyclops-bot tempoxyz-cyclops-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️ Cyclops Review

PR #3838 refactors TIP-1053 nonces from a zero-sentinel B256 into an explicit Option<B256>. Encoding determinism (trailing(canonical)), pre-T5 gating across validate_env / precompile / dispatch, atomic per-account (account, nonce) consumption, storage-layout shift, and intrinsic-gas accounting all check out. One verified actionable finding remains around txpool visibility of nonce consumption (inline). See workers' Reviewer Callouts below.

Reviewer Callouts
  • burnKeyAuthorizationNonce is the first stateful AccountKeychain mutation callable by access keys. ensure_nonce_burn_caller only requires tx_origin == msg_sender plus an active access key; per-call scope rules are enforced one layer up. Because the calldata first word is the nonce (not an address), recipients scoping cannot meaningfully restrict which nonces a scoped key can burn. Confirm this broadening for legacy/unscoped keys is intentional before T5.
  • Same-tx auth+use ordering. Any future change that lets an access key drive burnKeyAuthorizationNonce before the symmetric ensure_admin_caller gate runs must keep ensure_nonce_burn_caller in sync.
  • Reverted batch permanently burns the nonce. Per design, KeyAuthorization state commits before the AA batch executes; if the batch reverts, the key remains authorized and the TIP-1053 nonce remains consumed. Worth surfacing in wallet/UX docs.
  • is_legacy_compatible is currently unreferenced. Updated to consider has_nonce() but has no callers. Confirm whether a downstream encoder/serializer is expected to consult it before T5.
  • Provider/SDK gap. crates/alloy/src/provider/keychain.rs lacks helpers for authorizeKey_2 and burnKeyAuthorizationNonce; SDK consumers must hand-encode until helpers are added.

Comment thread crates/precompiles/src/account_keychain/mod.rs
Comment thread crates/precompiles/src/account_keychain/mod.rs
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

📊 Tempo Precompiles Coverage

precompiles

Coverage: 5665/7842 lines (72.24%)

File details
File Lines Coverage
src/account_keychain/dispatch.rs 33/84 39.29%
src/account_keychain/mod.rs 296/813 36.41%
src/address_registry/dispatch.rs 31/33 93.94%
src/address_registry/mod.rs 50/56 89.29%
src/error.rs 39/114 34.21%
src/ip_validation.rs 10/10 100.00%
src/lib.rs 181/216 83.80%
src/nonce/dispatch.rs 9/10 90.00%
src/nonce/mod.rs 46/61 75.41%
src/signature_verifier/dispatch.rs 19/20 95.00%
src/signature_verifier/mod.rs 13/17 76.47%
src/stablecoin_dex/dispatch.rs 92/93 98.92%
src/stablecoin_dex/mod.rs 866/918 94.34%
src/stablecoin_dex/order.rs 110/161 68.32%
src/stablecoin_dex/orderbook.rs 157/216 72.69%
src/storage/evm.rs 192/221 86.88%
src/storage/hashmap.rs 0/158 0.00%
src/storage/mod.rs 27/27 100.00%
src/storage/packing.rs 68/93 73.12%
src/storage/thread_local.rs 165/227 72.69%
src/storage/types/array.rs 0/72 0.00%
src/storage/types/bytes_like.rs 91/183 49.73%
src/storage/types/mapping.rs 27/48 56.25%
src/storage/types/mod.rs 70/97 72.16%
src/storage/types/primitives.rs 21/24 87.50%
src/storage/types/set.rs 28/192 14.58%
src/storage/types/slot.rs 55/81 67.90%
src/storage/types/vec.rs 103/261 39.46%
src/tip20/dispatch.rs 149/165 90.30%
src/tip20/mod.rs 591/693 85.28%
src/tip20/rewards.rs 238/252 94.44%
src/tip20/roles.rs 107/110 97.27%
src/tip20_factory/dispatch.rs 17/18 94.44%
src/tip20_factory/mod.rs 105/125 84.00%
src/tip403_registry/dispatch.rs 55/56 98.21%
src/tip403_registry/mod.rs 334/371 90.03%
src/tip_fee_manager/amm.rs 286/364 78.57%
src/tip_fee_manager/dispatch.rs 81/83 97.59%
src/tip_fee_manager/mod.rs 71/136 52.21%
src/validator_config/dispatch.rs 38/52 73.08%
src/validator_config/mod.rs 171/227 75.33%
src/validator_config_v2/dispatch.rs 71/73 97.26%
src/validator_config_v2/mod.rs 552/611 90.34%

contracts

Coverage: 1/258 lines (0.39%)

File details
File Lines Coverage
src/lib.rs 1/1 100.00%
src/precompiles/account_keychain.rs 0/48 0.00%
src/precompiles/address_registry.rs 0/12 0.00%
src/precompiles/nonce.rs 0/15 0.00%
src/precompiles/signature_verifier.rs 0/3 0.00%
src/precompiles/stablecoin_dex.rs 0/18 0.00%
src/precompiles/tip20.rs 0/58 0.00%
src/precompiles/tip20_factory.rs 0/9 0.00%
src/precompiles/tip403_registry.rs 0/24 0.00%
src/precompiles/tip_fee_manager.rs 0/18 0.00%
src/precompiles/validator_config.rs 0/13 0.00%
src/precompiles/validator_config_v2.rs 0/39 0.00%

Total: 5666/8100 lines (69.95%)

📦 Download full HTML report

Copy link
Copy Markdown

@tempoxyz-cyclops-bot tempoxyz-cyclops-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️ Cyclops Review — PR #3838 (TIP-1053 Key Authorization Nonces)

Summary

PR #3838 implements TIP-1053: an optional bytes32 nonce field in KeyAuthorization payloads with per-account single-use enforcement, gated behind T5. Three workers traced the full lifecycle (RLP encoding → signature hash → handler validation → precompile dispatch → storage write → event extraction → pool eviction) and core invariants hold (legacy byte-equivalence on nonce: None, signature hash binds the nonce, T5 hardfork gating in dispatch + handler + precompile, pool/execution parity, single-use storage, atomicity of pre-checks before nonce consumption). One verified gas-undercharge bug remains — see inline comment.

Reviewer Callouts
  • Pre-consume validation fragility (crates/precompiles/src/account_keychain/mod.rs:287-302): The "fail before consuming the nonce" property holds only as long as apply_key_authorization_restrictions / replace_allowed_calls keep re-validating the same conditions that t3_spending_limit_cap and validate_call_scopes cover. Adding a new check in apply_* not mirrored in pre-validate would let a bad payload burn a nonce while rolling back the auth.
  • Open keychain checkpoint pattern (crates/revm/src/handler.rs:1267-1420, pre-existing): When the keychain StorageCtx::enter closure returns Err, ? propagates and keychain_checkpoint is left open; nonce-burn atomicity now also relies on the upstream block executor reverting state for invalid txs. Not introduced by this PR, but the new persistent write expands the blast radius.
  • Access-key burn power (burnKeyAuthorizationNonce): ensure_nonce_burn_caller lets any active access key burn nonces, gated only by the access key's call-scope rules (crates/precompiles/src/account_keychain/mod.rs:1057-1069). Wallets that grant unrestricted access keys are implicitly granting "burn any nonce". Spec-consistent, but a real footgun for SDK/wallet UX.
  • is_bad_transaction() classification of nonce reuse (crates/revm/src/error.rs:298): KeychainPrecompileError is treated as state-dependent, but KeyAuthorizationNonceAlreadyUsed is permanent — the tx will never become valid again. Misclassification keeps peers re-broadcasting these txs. Minor DoS surface; one-line allowlist for the specific subcase would help.
  • Reorg consistency for nonce eviction (crates/transaction-pool/src/maintain.rs:398-420): When a block emitting KeyAuthorizationNonceConsumed is reorged out, sibling AA txs evicted on that event are not automatically re-admitted — same class as SIGP-TMPO2-22. The nonce-eviction set should be invalidated/recomputed on reorg alongside revoked_keys / spending_limit_*.
  • is_legacy_compatible() is now dead code (crates/primitives/src/transaction/key_authorization.rs:312-313): Updated to disqualify nonce-bearing auths but no caller exists. Confirm intent before any future caller is added.
  • T5 activation checklist: All workers note this feature is dormant on the active T2 hardfork. Before T5 is scheduled, re-review the live execution paths with T5 enabled — especially direct AccountKeychain caller behavior, pool hygiene under real nonce-consumption events, and the post-consume_key_authorization_nonce failure paths in crates/precompiles/src/account_keychain/mod.rs:317-342, 1072-1080.
  • Gas pinning regression: The new pinned test at crates/revm/src/handler.rs:3081-3090 only asserts the delta between base and nonce variants; any BUFFER value satisfies it. Add an absolute-value pinning test against an independently computed expected gas including all events emitted on the path.

Comment thread crates/revm/src/handler.rs Outdated
@jenpaff jenpaff added the T5 label May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cyclops Trigger Cyclops PR audit T5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants